class EventEmitter {
    events = new Map();
    constructor() {

    }
    on(evtName, fn, isOnce = false) {
        if (typeof fn !== "function") {
            throw new TypeError("The listener must be a function!");
        }
        if(this.events.has(evtName) == false) {
            this.events.set(evtName, []);
        }
        let evtArr = this.events.get(evtName);
        evtArr.push({isOnce: isOnce, fn: fn});
    }
    once(evtName, fn) {
        this.on(evtName, fn, true);
    }
    emit(evtName, ...args) {
        let evtArr = this.events.get(evtName);
        if(evtArr == undefined) {
            return false;
        }
        for(let evtObj of evtArr) {
            evtObj.fn.call(null, ...args);
            if(evtObj.isOnce == true) {
                this.removeListener(evtName, evtObj.fn);
            }
        }
    }
    removeListener(evtName, fn) {
        let evtArr = this.events.get(evtName);
        if(evtArr == undefined) {
            return false;
        }
        for(let i = 0; i < evtArr.length; i++) {
            if(evtArr.fn == fn) {
                evtArr.splice(index, 1);
            }
        }
    }
    off(eventName, fn) {
        this.removeListener(eventName, fn);
    }
}
